<?php


namespace app\api\controller;

use app\common\controller\Api;
use think\Db;
use think\Request;
use Yansongda\Pay\Pay as ePay;
use Yansongda\Pay\Log;
use Yansongda\Pay\Exceptions\InvalidConfigException;
use Yansongda\Pay\Exceptions\InvalidSignException;
class Pay extends Api {

    protected $noNeedLogin = ['wechatNotify','courseNotify1','courseNotify','testnotify'];//空代表都需要验证
    protected $noNeedRight = ['*'];
    //用户端
    protected $weChatConfig = [
        'appid' => 'wx3875a6c73b771c8a', // APP APPID
        'app_id' => 'wxd4873aabcd30a087', // 公众号 APPID
        'miniapp_id' => 'wx6c9c5f311459d492', // 小程序 APPID
        'mch_id' => '1603559845',
        'key' => 'ZKVgDxdxvU5OnhGUIpBKWtcgNZMk9LwG',
        'notify_url' => '123',
        'cert_client' => './cert/apiclient_cert.pem', // optional，退款等情况时用到
        'cert_key' => './cert/apiclient_key.pem',// optional，退款等情况时用到
        'log' => [ // optional
            'file' => './logs/wechat.log',
            'level' => 'debug', // 建议生产环境等级调整为 info，开发环境为 debug
            'type' => 'single', // optional, 可选 daily.
            'max_file' => 30, // optional, 当 type 为 daily 时有效，默认 30 天
        ],
        'http' => [ // optional
            'timeout' => 10.0,
            'connect_timeout' => 10.0,
            // 更多配置项请参考 [Guzzle](https://guzzle-cn.readthedocs.io/zh_CN/latest/request-options.html)
        ],
        'mode' => 'normal', // optional, dev/hk;当为 `hk` 时，为香港 gateway。
    ];
    // 支付宝配置文件
    protected $configAli = [
        'app_id'=>2021002126647642,

        'notify_url'=>'',

        'return_url'=>'http://yansongda.cn/return.php',

        'ali_public_key'=>'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArELCSYz2UxwUE9hzISWXCSITP4tr5QYAJ9T/Vs/hKhKiXQDyv/lLo5wRy2lHDwn2a1NJ4zsYdW3pxFI3LlBIM2fnx4c10Yfmgd3YFxKGMM0kcBAPEngqmz/N6ZrOGwhU56sTG7a3IVNxuu707yLNRCOu7J7l7j62eQ/FfIegG+1nqvYlu3WGNhFKC5Bg0P6ZqX0Z2ft+/Sdp4mbCVR44Rv7cvgbIkN+G3R65G7HIQRb6JT2oDguvZQvVagaLm6/k6FRLRR+rlw+chXwiyprhNZr/AjQ8oPwBOCDDNnGTlNZmVMGLM76pE/l9M+CzFQo1ARDJRoyOaUHX7vmdthXmmQIDAQAB',

        'private_key'=>'MIIEpQIBAAKCAQEArELCSYz2UxwUE9hzISWXCSITP4tr5QYAJ9T/Vs/hKhKiXQDyv/lLo5wRy2lHDwn2a1NJ4zsYdW3pxFI3LlBIM2fnx4c10Yfmgd3YFxKGMM0kcBAPEngqmz/N6ZrOGwhU56sTG7a3IVNxuu707yLNRCOu7J7l7j62eQ/FfIegG+1nqvYlu3WGNhFKC5Bg0P6ZqX0Z2ft+/Sdp4mbCVR44Rv7cvgbIkN+G3R65G7HIQRb6JT2oDguvZQvVagaLm6/k6FRLRR+rlw+chXwiyprhNZr/AjQ8oPwBOCDDNnGTlNZmVMGLM76pE/l9M+CzFQo1ARDJRoyOaUHX7vmdthXmmQIDAQABAoIBAQCIfNDiZB1cVpgV7V+zeMxGQUiNBdQ0f9+pr9utFkMrCd654CF3OHjVJrj2ufDCmrsz6KdXsyA7Ex6xHg9408WRbZe5gYmD/rEGXxdzmIrYqgJgBGlc0fe4UQK/QJhj1OMpOGSIhepuLmajnehWffW0Mq3L8E7wyaHdJEDu3atf1BtI9Up87/JhuRf1zMImydU7ZGgRYPCvz+8F1Uk1hdxa2oiGLfLlBrkxNmXb+FoMfvANZbJG3TvZwn6lB3HzAnbQnhp+FY8NKGKAs/h3ahG6rjGHGfk/SEnNSBkV9sGdE5jUI71gGMaUBEhg9m1QUqea4Zt7pv8VoPSMlnRV09kBAoGBANr03us6Fq4QhgC72D2wTJHeF5r/9kSrGs/jWva6FbXgQu27Ue1eXZI5MjrkyxitzyOoy/BRGeXtjzD8YTKxcsIB/tVogF4oCjw5aZC4Nj81YhruwVrc7bRrjSL10k7NQ1MX2Zm0bJN6vu/kgwycO9XZTP7PN3yvjlxS4j7aV0N5AoGBAMlneB7aFCc9gGSEAhtt5jbhO7Oflw1JRA4TAE2lJPI618gFSFOvwtQRchsAWYKk4XqAJJgtqpbgCSAiWDt+1jawN7eY8+9hbUXJwrBibxQqgxsoSlIyt4WR9uPCMrPMjYJ4RnLpHNtWPFRr69wRMAaEKWqDJu5BgzKUORZRJtQhAoGBAKwE9Z2YZXkbQiwRaDIO8BkpgyIjNjd8tfPdivmL+MKLDgn3wMXb/WeDyBK87VLWOoapdo+3J8GcgYLaxQIupxoEt1CyaSeQDXqDIIyyLOw75HeEXCQmrhmw5ZExz6hZWytM8YfwV90F8jxGKy8dD2VS80q9QbqTsiSWeWkn4KcBAoGALeZ+4ckhvq+tizrqoAWz6d37FTzR2B1SfUKnVwrEGNCATP2nNitgY6R2NOEnhTa+jISX0nbV4fy9F628HhMSDvSqPhWFwpCZrsYEsN4+IoJtzsqn5YPZf398nPutQnzj41A1/gpSoUpOBY9y+XyRTWrhZXzuam5T0Dsnp4ZnKwECgYEAq0OrR1eFPp6sMEFglke1QRyM70ssvaB9G63P00M55VMqo7dvjkQYp+AW4Y+9w49cqwIeF1ZwtYfZMOxZ5GfiDSBIJs0yynDkVqBGo2N5GrsLPZhijhATALuqxtrHtPro6EapaP0Oyvje2fh1KjkIiNuCi5wR+qB7BpEDN2cCY6Q=',

        'log' => [ // optional
            'file' => './logs/alipay.log',
            'level' => 'info', // 建议生产环境等级调整为 info，开发环境为 debug
            'type' => 'single', // optional, 可选 daily.
            'max_file' => 30, // optional, 当 type 为 daily 时有效，默认 30 天
        ],
        'http' => [ // optional
            'timeout' => 5.0,
            'connect_timeout' => 5.0,
            // 更多配置项请参考 [Guzzle](https://guzzle-cn.readthedocs.io/zh_CN/latest/request-options.html)
        ],
        'mode' => 'normal', // optional,设置此参数，将进入沙箱模式
    ];



    /**
     * @DESC:
     * @param $order
     * @param $price
     * @param $user
     * @author: renyixu
     * @Time: 2020/11/6   3:46 下午
     *公众号微信支付
     */
    public function weChat($order,$price,$user){
        $all_price = $price * 100;
        $order = [
            'out_trade_no' => $order,
            'body' => '商品支付',
            'total_fee' => $all_price,
            'openid' => $user,
        ];
        $this->weChatConfig['notify_url']='http://kuajing123.191292.net/api/pay/wechatNotify';
        $pay = ePay::wechat($this->weChatConfig)->mp($order);
      // $pay=toArray($pay);
        $this->success('请求成功!', ['info'=>$pay]);
    }

    /**
     * @DESC:
     * @param Request $request
     * @return \Symfony\Component\HttpFoundation\Response
     * @author: renyixu
     * @Time: 2020/11/6   4:03 下午
     * 公众号支付回调
     */
    public function wechatNotify()
    {
        $pay = ePay::wechat($this->weChatConfig);//实例化支付对象
        try{
            $data = $pay->verify(); // 是的，验签就这么简单！
            //以下根据自己业务进行支付校验
            $order = \app\common\model\Order::where('order_sn', $data->out_trade_no)->find();
            if (!$order || $order->status != 1)  {
                //如果订单状态异常直接退出
                return $pay->success();
            }
            $total_fee=bcdiv($data->total_fee,100,2);
            \app\common\model\Order::where('order_sn', $data->out_trade_no)->update(['status'=>2,'mode'=>1,'paytime'=>time(),'money'=>$total_fee]);
            Log::debug('Wechat notify', $data->all());
            return $pay->success();
        } catch (\Exception $e) {
        }
    }

    public function refund($order_sn,$money,$mode=2){
        if($mode==1){
            $money=$money*100;
            $alipay = ePay::wechat($this->weChatConfig);
            $order = [
                'out_trade_no' => $order_sn,
                'out_refund_no' => time(),
                'total_fee' => $money,
                'refund_fee' => $money,
                'refund_desc' => '退款',
            ];
        }else{
            $alipay = ePay::alipay($this->configAli);
            $order = [
                'out_trade_no' => $order_sn,
                'refund_amount' => $money,
            ];
        }
        try{
            //
            //            dd($order);
            $result = $alipay->refund($order);
            //            dd($result);
        } catch (\Exception $e) {
            $e->getMessage();
        }
    }

    /**
     * 统一下单接口
     * $pay_mode1微信2支付宝
     * $amount支付金额
     * $order_type 1用户订单2商户订单
     * $order_sn用户订单号
     * $notify_url 回调地址
     * $body 购买提示语
     * $extra 额外参数
     */
    public function pay($pay_mode, $price, $order_sn,$notify_url,$body,$extra=null) {
        // $price = 0.01;
        if ($pay_mode == 1) {
            $result = $this->wechatindex($order_sn, $price,$notify_url.'1',$body,$extra);
//            dd($result);
        } else {
            $result = $this->aliIndex($order_sn, $price,$notify_url,$body,$extra);
        }
        return $result;
    }

    /**
     * 微信支付-app
     * @param $order_sn
     * @param $price
     */
    public function wechatindex($order_sn, $price,$notify_url,$body,$extra='') {
//        $price = 0.01;
        $all_price = $price * 100;
//        //测试账号，支付0.01
//        $user_id = $this->auth->id;
//        $rs = cs_user();
//        if(in_array($user_id,$rs)){
//            $all_price=0.01;
//        }
        $order = [
            'out_trade_no' => $order_sn,
            'body' => $body,
            'total_fee' => $all_price,
        ];
        $this->weChatConfig['notify_url'] = $notify_url;
//        $this->weChatdocConfig = config('wetch');
//        $this->weChatdocConfig['notify_url']=$notify_url;

        $pay = ePay::wechat($this->weChatConfig)->app($order);
        $cc = $pay->getContent();
        $aa = json_decode($cc, true);
        $this->success('success', ['info'=>$aa,'order_sn'=>$order_sn,'data'=>$extra]);

    }

    /**
     * 支付宝支付-app
     * @throws \Yansongda\Pay\Exceptions\InvalidConfigException
     * @throws \Yansongda\Pay\Exceptions\InvalidSignException
     */
    public function aliIndex($order_sn, $all_price,$notify_url,$body,$extra='') {
        $user_id = $this->auth->id;
        //测试账号，支付0.01
//        $rs = cs_user();
//        if(in_array($user_id,$rs)){
//            $all_price=0.01;
//        }
        $order = [
            'out_trade_no' => $order_sn,
            'total_amount' => $all_price,
            'subject' => $body,
        ];
//        $this->configAli=config('alipay');
        $this->configAli['notify_url']=$notify_url;
        $alipay = ePay::alipay(  $this->configAli)->app($order);
        $cc = $alipay->getContent();
        $aa['info'] = $cc;
        $this->success('success', ['info'=>$aa,'order_sn'=>$order_sn,'data'=>$extra]);

    }

    /**
    /**
     * 支付宝支付-web
     * @throws \Yansongda\Pay\Exceptions\InvalidConfigException
     * @throws \Yansongda\Pay\Exceptions\InvalidSignException
     */
    public function webaliIndex($order_sn, $all_price,$notify_url,$body,$extra='') {
        $user_id = $this->auth->id;
        //测试账号，支付0.01
//        $rs = cs_user();
//        if(in_array($user_id,$rs)){
//            $all_price=0.01;
//        }
        $order = [
            'out_trade_no' => $order_sn,
            'total_amount' => $all_price,
            'subject' => $body,
        ];
//        $this->configAli=config('alipay');
        $this->configAli['notify_url']=$notify_url;
        $alipay = ePay::alipay(  $this->configAli)->scan($order);
        $cc = $alipay->getContent();
        $aa['info'] = $cc;
        $this->success('success', ['info'=>$aa,'order_sn'=>$order_sn,'data'=>$extra]);

    }

    /**
     * @return \Symfony\Component\HttpFoundation\Response
     * 支付宝 订单支付回调
     */
    public function courseNotify()
    {
        $request=input();
        $alipay = ePay::alipay($this->configAli);
        try{
//            $data = $alipay->verify($request); // 是的，验签就这么简单！
            $data = $request; // 是的，验签就这么简单！
            // 请自行对 trade_status 进行判断及其它逻辑进行判断，在支付宝的业务通知中，只有交易通知状态为 TRADE_SUCCESS 或 TRADE_FINISHED 时，支付宝才会认定为买家付款成功。
            // 1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号；
            // 2、判断total_amount是否确实为该订单的实际金额（即商户订单创建时的金额）；
            // 3、校验通知中的seller_id（或者seller_email) 是否为out_trade_no这笔单据的对应的操作方（有的时候，一个商户可能有多个seller_id/seller_email）；
            // 4、验证app_id是否为该商户本身。
            // 5、其它业务逻辑情况
            $model=new \app\common\model\Order();
            $order_sn=$data['out_trade_no'];
            $trade_status=$data['trade_status'];

            $info=$model->where('order_sn','=',$order_sn)->find();

            if ($trade_status=='TRADE_SUCCESS'){
                //以下根据自己业务进行支付校验
                $order = \app\common\model\Order::where('order_sn', $data['out_trade_no'])->find();
                if (!$order || $order->status != 1)  {
                    //如果订单状态异常直接退出
                    return $alipay->success();
                }
                $total_fee=bcdiv($data['total_amount'],100,2);
                \app\common\model\Order::where('order_sn', $data['out_trade_no'])->update(['status'=>2,'mode'=>2,'paytime'=>time()]);
            }

            //    Log::debug('Alipay notify', $data->all());
            // 提交事务
            Db::commit();
        } catch (\Exception $e) {
            // $e->getMessage();
            // 回滚事务
            Db::rollback();
        }

        return $alipay->success()->send();// laravel 框架中请直接 `return $alipay->success()`
//        return true;// laravel 框架中请直接 `return $alipay->success()`
    }

    /**
     * @return \Symfony\Component\HttpFoundation\Response
     * 微信 订单支付回调
     */
    public function courseNotify1()
    {
        $pay = ePay::wechat($this->weChatConfig);//实例化支付对象
        try{
            $data = $pay->verify(); // 是的，验签就这么简单！
            //以下根据自己业务进行支付校验
            $order = \app\common\model\Order::where('order_sn', $data->out_trade_no)->find();
            if (!$order || $order->status != 1)  {
                //如果订单状态异常直接退出
                return $pay->success();
            }
            $total_fee=bcdiv($data->total_fee,100,2);
            \app\common\model\Order::where('order_sn', $data->out_trade_no)->update(['status'=>2,'mode'=>1,'paytime'=>time(),'money'=>$total_fee]);
            Log::debug('Wechat notify', $data->all());
            return $pay->success();
        } catch (\Exception $e) {
        }
    }

    /**
     * 统一下单接口
     * $pay_mode1微信2支付宝
     * $amount支付金额
     * $order_type 1用户订单2商户订单
     * $order_sn用户订单号
     * $notify_url 回调地址
     * $body 购买提示语
     * $extra 额外参数
     */
    public function webpay($pay_mode, $price, $order_sn,$notify_url,$body,$extra=null) {

        if ($pay_mode == 1) {
            $result = $this->webwechatindex($order_sn, $price,$notify_url.'1',$body,$extra);
        } else {
            $result = $this->webaliIndex($order_sn, $price,$notify_url,$body,$extra);
        }
        return $result;
    }
    /**
     * 微信支付-pc 支付
     * @param $order_sn
     * @param $price
     */
    public function webwechatindex($order_sn, $price,$notify_url,$body,$extra='') {
//        $price = 0.01;
        $all_price = $price * 100;
        $order = [
            'out_trade_no' => $order_sn,
            'body' => $body,
            'total_fee'      => $all_price,
        ];
        $this->weChatWebdocConfig = $this->weChatConfig;

        $this->weChatWebdocConfig['app_id']=$this->weChatWebdocConfig['appid'];
        $this->weChatWebdocConfig['notify_url']=$notify_url;


        $pay = ePay::wechat($this->weChatWebdocConfig)->scan($order);
//        dd($pay);
        $qr  = qrcode($pay->code_url,$order_sn);
        $this->success('success', ['info'=>$qr,'order_sn'=>$order_sn,'data'=>$extra]);

    }
    //小程序支付
    public function payMniapp($price, $order_sn,$notify_url,$body,$extra=[]) {
     //   $price = 0.01;

        $result = $this->wechatindexMniapp($order_sn, $price,$notify_url.'1',$body,$extra);

        return $result;
    }
    /**
     * 微信支付-小程序
     * @param $order_sn
     * @param $price
     */
    public function wechatindexMniapp($order_sn, $price,$notify_url,$body,$extra=[]) {

        $all_price = $price * 100;
        //测试账号，支付0.01

//        $this->weChatConfig = config('wetch');
        $this->weChatConfig['notify_url']=$notify_url;
//        $this->weChatdocConfig['key']= config('wetch.miniapp_key');

        $order = [
            'out_trade_no' => $order_sn,
            'body' => $body,
            'total_fee' => $all_price,
            'openid' => $extra['openid'],
        ];
//        ePay::wechat($this->weChatdocConfig)
//        $result = $wechat->miniapp($order);
        $pay = ePay::wechat($this->weChatConfig)->miniapp($order);


//        $cc = $pay->getContent();
        $aa = json_decode($pay, true);
        $this->success('success', ['info'=>$aa,'order_sn'=>$order_sn,'data'=>$extra]);

    }
}